Java反射操作私有成员或方法、实例化私有内部类

您所在的位置:网站首页 java 调用其它类的私有方法是什么 Java反射操作私有成员或方法、实例化私有内部类

Java反射操作私有成员或方法、实例化私有内部类

2024-07-10 20:32| 来源: 网络整理| 查看: 265

文章目录 预备知识递归地打印父类getSuperclass()Class的newInstance方法操作私有成员(取值,赋值)调用私有方法创建private内部类的实例

预备知识 通过 实例.getClass() 返回实例的运行时类类型的Class引用。通过 类名.class 可以获得Class引用(前提是你可以import这个类,好处是使用.class来创建对Class对象的引用时,不会自动地初始化该Class对象)。通过 Class.forName(类名的全称) 也可以获得Class引用。其方法声明为public static Class forName(String className),注意泛型为?。 递归地打印父类getSuperclass() package com.prac; class A{} class B extends A {} class C extends B {} public class testRecur { static void printInfo(Class cc){ System.out.println("name: "+cc.getName()); System.out.println("is interface? "+cc.isInterface()); System.out.println("simple name: "+cc.getSimpleName()); System.out.println("canonical name: "+cc.getCanonicalName()); System.out.println(); } static void f(Class c){ printInfo(c); try{ f(c.getSuperclass()); }catch(Exception e){ } } public static void main(String[] args) { Class c = null; try{ c = Class.forName("com.prac.C"); //c = C.Class;也能有同样效果 f(c); }catch(ClassNotFoundException e){} } }

打印结果如下:

name: com.prac.C is interface? false simple name: C canonical name: com.prac.C name: com.prac.B is interface? false simple name: B canonical name: com.prac.B name: com.prac.A is interface? false simple name: A canonical name: com.prac.A name: java.lang.Object is interface? false simple name: Object canonical name: java.lang.Object

很可惜,getSuperclass这个方法只能看到native,方法声明为@HotSpotIntrinsicCandidate public native Class c = C.class时,newInstance返回的对象的类型为Object。当声明初始化语句为Class制定的泛型是?(newInstance的方法声明为public T newInstance(Object ... initargs),从这里可以看出返回类型为T,但由于创建时指定的是?),所以con.newInstance(out)只能返回Object引用,虽然你已经创建了normalInner的实例。现在有Object引用指向了normalInner的实例,通过获得Field,一样可以获得实例的成员变量。(这点很关键,因为原来我以为这种引用是无法获得成员的,但反射可能只跟对象的RTTI有关,无所谓引用是不是基类Object) import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Field; import com.prac.outer; public class testInner { public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { outer out = new outer(); Class staticClazz = null; try { staticClazz = Class.forName("com.prac.outer$staticInner"); System.out.println(staticClazz.getName()); } catch (ClassNotFoundException e) { e.printStackTrace(); } Constructor con = staticClazz.getDeclaredConstructor(); con.setAccessible(true); Object obj = con.newInstance(); try { Field field = staticClazz.getDeclaredField("j"); field.setAccessible(true); System.out.println(field.get(obj)); } catch (NoSuchFieldException e) { System.out.println("get field failed"); e.printStackTrace(); } } }

同样,对私有静态内部类进行测试。打印结果:

com.prac.outer$staticInner 2


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3